﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

using D6.DFS.Consumer.ContextRegistryService;
using D6.DFS.Consumer.SchemaService;
using D6.DFS.Consumer.SearchService;
using D6.DFS.Consumer.ObjectService;
using D6.DFS.Consumer.QueryService;

namespace D6.DFS.Consumer
{
    public abstract class DfsConsumer
    {


        #region Attributes

        protected Repository[] m_repositoryList= null;
        protected ServiceContextHeader m_scx = null;
        protected SearchServicePortClient m_searchService = null;
        protected SchemaServicePortClient m_schemaService = null;
        protected ObjectServicePortClient m_objectService = null;
        protected QueryServicePortClient m_queryService = null;

        protected Repository m_currRepository = null;
        protected String m_currRepositoryName = null;
        protected String m_currRepositoryUserLogin = null;
        protected String m_currRepositoryUserPassword = null;

        protected Int32 m_total_results_to_return = 4;

        protected String m_exceptionInfo = null;

#endregion Attributes

#region Properties
        public String[] Repositories
        {
            get
            {
                List<String> repositoryNames = new List<String>();

                foreach (Repository repositoryItem in GetRepositoryList())
                {
                    repositoryNames.Add(repositoryItem.name);
                }

                return repositoryNames.ToArray();
            }
        }

        public String ErrorMessage
        {
            get
            {
                return m_exceptionInfo;
            }
        }

        public Int32 Results_To_Return
        {
            get
            {
                return m_total_results_to_return;
            }
            set
            {
                m_total_results_to_return = value;
            }
        }


#endregion Properties


        #region Methods

        public DfsConsumer()
        {
            m_searchService = new SearchServicePortClient("SearchServicePort");
            m_schemaService = new SchemaServicePortClient("SchemaServicePort");
            m_objectService = new ObjectServicePortClient("ObjectServicePort");
            m_queryService = new QueryServicePortClient("QueryServicePort");

            m_scx = new ServiceContextHeader();
            RepositoryIdentity repositoryId = new RepositoryIdentity();
            repositoryId.repositoryName = "DMS";
            repositoryId.userName = "";
            repositoryId.password = "";

            m_scx.AddRepositoryIdentity(repositoryId);
        }

        public DfsConsumer(String repository, String username, String password)
        {
            m_searchService = new SearchServicePortClient("SearchServicePort");
            m_schemaService = new SchemaServicePortClient("SchemaServicePort");
            m_objectService = new ObjectServicePortClient("ObjectServicePort");
            m_queryService = new QueryServicePortClient("QueryServicePort");

            m_scx = new ServiceContextHeader();
            RepositoryIdentity repositoryId = new RepositoryIdentity();
            repositoryId.repositoryName = repository;
            repositoryId.userName = username;
            repositoryId.password = password;

            m_currRepositoryName = repositoryId.repositoryName;

            m_scx.AddRepositoryIdentity(repositoryId);
        }


        protected Repository[] GetRepositoryList()
        {
            if (null == m_repositoryList || m_repositoryList.Count() == 0)
            {
                try
                {

                    using (OperationContextScope scope = new OperationContextScope(new OperationContext(m_searchService.InnerChannel)))
                    {
                        OperationContext.Current.OutgoingMessageHeaders.Add(m_scx);
                        m_repositoryList = m_searchService.getRepositoryList(null);
                    }


                }
                catch (Exception ex)
                {
                    m_exceptionInfo = ex.ToString();
                }

            }

            return m_repositoryList;
        }

        protected void getDctmObject(String customType)
        {
            D6.DFS.Consumer.ObjectService.DataPackage dataPackage = null;

            try
            {
                //find the custom type to return
                D6.DFS.Consumer.ObjectService.Qualification q = new D6.DFS.Consumer.ObjectService.Qualification();
                q.String = "dm_type WHERE name = '" + customType + "'";
                q.qualificationValueType = D6.DFS.Consumer.ObjectService.QualificationValueType.STRING;
                q.qualificationValueTypeSpecified = true;

                //Set the identity
                D6.DFS.Consumer.ObjectService.ObjectIdentity objId = new D6.DFS.Consumer.ObjectService.ObjectIdentity();
                objId.valueType = D6.DFS.Consumer.ObjectService.ObjectIdentityType.QUALIFICATION;
                objId.valueTypeSpecified = true;
                objId.Item = q;
                objId.repositoryName = m_currRepositoryName;

                D6.DFS.Consumer.ObjectService.ObjectIdentitySet objectIdSet = new D6.DFS.Consumer.ObjectService.ObjectIdentitySet();
                objectIdSet.Identities = new D6.DFS.Consumer.ObjectService.ObjectIdentity[1];
                objectIdSet.Identities[0] = objId;

                D6.DFS.Consumer.ObjectService.PropertyProfile propertyProfile = new D6.DFS.Consumer.ObjectService.PropertyProfile();
                String[] attributes = new String[1];
                attributes[0] = "test_value_assistance";
                propertyProfile.IncludeProperties = attributes;

                D6.DFS.Consumer.ObjectService.OperationOptions opsOptions = new D6.DFS.Consumer.ObjectService.OperationOptions();
                opsOptions.Profiles = new D6.DFS.Consumer.ObjectService.Profile[1];
                opsOptions.Profiles[0] = propertyProfile;

                using (OperationContextScope scope = new OperationContextScope(m_objectService.InnerChannel))
                {
                    OperationContext.Current.OutgoingMessageHeaders.Add(m_scx);
                    //m_schemaService.getDynamicAssistValues("DMS", "DEFAULT", "dlau_custom_type", "value_assistance", property_set, null);

                    dataPackage = m_objectService.get(objectIdSet, opsOptions);


                }

            }
            catch (Exception ex)
            {
                m_exceptionInfo = ex.ToString();
            }
        }


        public void setCurrentRepository(String currRepositoryName, String username, String password)
        {
            if (String.IsNullOrEmpty(currRepositoryName))
            {
                return;
            }
            if (null == m_repositoryList || m_repositoryList.Count() == 0)
            {
                return;
            }
            if (String.IsNullOrEmpty(username))
            {
                return;
            }
            if (String.IsNullOrEmpty(password))
            {
                return;
            }

            m_currRepositoryName = currRepositoryName;
            m_currRepositoryUserLogin = username;
            m_currRepositoryUserPassword = password;

            IEnumerable<Repository> rCurrRepository = null;

            try
            {
                rCurrRepository = from Repository r in m_repositoryList
                                  where r.name.Equals(currRepositoryName)
                                  select r;
            }
            catch (Exception ex)
            {
                m_exceptionInfo = ex.ToString();
            }

            try
            {
                if (null == rCurrRepository || rCurrRepository.Count() == 0)
                {
                    return;
                }

                m_currRepository = rCurrRepository.First<Repository>();
            }
            catch (Exception ex)
            {
                m_exceptionInfo = ex.ToString();
            }

            m_scx = new ServiceContextHeader();
            RepositoryIdentity repositoryId = new RepositoryIdentity();
            repositoryId.repositoryName = m_currRepository.name;
            repositoryId.userName = m_currRepositoryUserLogin;
            repositoryId.password = m_currRepositoryUserPassword;

            m_scx.AddRepositoryIdentity(repositoryId);


        }


        public void executeDQL(String dqlStr)
        {

            if (String.IsNullOrEmpty(dqlStr))
            {
                return;
            }

            try
            {

                using (OperationContextScope scope = new OperationContextScope(m_queryService.InnerChannel))
                {
                    OperationContext.Current.OutgoingMessageHeaders.Add(m_scx);
                    D6.DFS.Consumer.QueryService.PassthroughQuery query = new D6.DFS.Consumer.QueryService.PassthroughQuery();
                    query.queryString = dqlStr;
                    query.repositories = new String[1];
                    query.repositories[0] = m_currRepositoryName;

                    D6.DFS.Consumer.QueryService.QueryExecution queryExec = new D6.DFS.Consumer.QueryService.QueryExecution();
                    queryExec.cacheStrategyType = D6.DFS.Consumer.QueryService.CacheStrategyType.DEFAULT_CACHE_STRATEGY;
                    queryExec.cacheStrategyTypeSpecified = true;
                    queryExec.maxResultCount = 4;

                    D6.DFS.Consumer.QueryService.QueryResult results = null;

                    results = m_queryService.execute(query, queryExec, null);

                    if (null != results)
                    {
                        processQueryResults(results);
                    }

                }



            }
            catch (Exception ex)
            {
                m_exceptionInfo = ex.ToString();
            }


        }

        protected abstract void processQueryResults(D6.DFS.Consumer.QueryService.QueryResult repositoryItems);


        #endregion Methods

    }
}
